<template>
  <div>
    <div id="container" name="container" class="dv-main"></div>
    <div style="position: absolute; bottom: 20px; left: 30%; margin: auto">
      <ul id="menu">
        <li
          v-for="(todo, index) in todos"
          :key="todo.text"
          v-on:click="addClass(index, $event)"
          v-bind:class="{ blue: index == current }"
        >
          {{ todo.text }}
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
import { PathPointList } from "../../../utils/three/PathPoint.js";
import { PathGeometry } from "../../../utils/three/PathGeometry";
import { TextureShader } from "../../../utils/three/testShader.js";
export default {
  name: "threeHello",
  data() {
    return {
      show: true,
      scene: null,
      texture: null,
      progress: 0.0,
      todos: [
        { text: "一楼" },
        { text: "二楼" },
        { text: "三楼" },
        { text: "重置" },
      ],
      current: -1,
      gltfModel: null,
    };
  },
  created: function () {},
  mounted() {
    this.init();
    this.initObject();
    this.loadModel("box.glb");
    this.animate();
  },
  methods: {
    login: function () {
      console.log(this.username, this.password);
    },
    init() {
      this.scene = new THREE.Scene();

      //初始化渲染器
      let container = document.getElementById("container");
      let height = container.offsetHeight;
      let width = container.offsetWidth;

      //初始化相机
      this.camera = new THREE.PerspectiveCamera(
        50,
        width / height,
        0.01,
        10000
      );

      this.camera.position.set(50, 50, 50);
      this.camera.lookAt(0, 0, 0);
      this.scene.add(this.camera);

      let hLight = new THREE.AmbientLight(0xffffff, 0.89);
      this.scene.add(hLight);

      let light1 = new THREE.DirectionalLight(0xffffff, 10);
      light1.position.set(50, 50, 50);
      this.scene.add(light1);

      this.renderer = new THREE.WebGLRenderer({
        antialias: true,
        alpha: true,
        logarithmicDepthBuffer: true,
      });
      this.renderer.setSize(width, height);
      container.appendChild(this.renderer.domElement);

      //初始化控制器
      this.controls = new OrbitControls(this.camera, this.renderer.domElement);

      this.controls.minDistance = 5;
      this.controls.maxDistance = 5000;
      // // 上下旋转范围
      this.controls.minPolarAngle = 0; // radians
      this.controls.maxPolarAngle = Math.PI * 0.5; // radians
      // // 左右旋转范围

      window.addEventListener("resize", this.onWindowResize, false);
    },
    onWindowResize() {
      let container = document.getElementById("container");
      let height = container.offsetHeight;
      let width = container.offsetWidth;

      this.camera.aspect = width / height;
      this.camera.updateProjectionMatrix();
      this.renderer.setSize(width, height);
    },
    initObject() {
      var points = [
        new THREE.Vector3(-20, 0.1, 12),
        new THREE.Vector3(-11.5, 0.1, 12),
        new THREE.Vector3(-11.5, 0.1, -1),
        new THREE.Vector3(9, 0.1, -1),
        new THREE.Vector3(9, 0.1, 5),
      ];

      var up = new THREE.Vector3(0, 1, 0);

      // 创建路线点列表
      var pathPointList = new PathPointList();
      pathPointList.set(points, 0.5, 10, up, false);

      // 创建 geometry
      var geometry = new PathGeometry();
      geometry.update(pathPointList, {
        width: 0.5,
        arrow: true,
      });

      this.texture = new THREE.TextureLoader().load(
        "/image/arrow.png",
        function (texture) {
          texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
        }
      );
      this.texture.repeat.set(0.2, 1);

      var mat = new THREE.MeshBasicMaterial({
        map: this.texture,
      });

      var uniforms = {
        uvScale: { value: new THREE.Vector2(0.2, 1) },
        time: { value: 0.0 },
        colorTexture: { value: this.texture },
      };

      uniforms["colorTexture"].value.wrapS = uniforms[
        "colorTexture"
      ].value.wrapT = THREE.RepeatWrapping;

      this.shaderMaterial = new THREE.ShaderMaterial({
        uniforms: uniforms,
        vertexShader: TextureShader.vetexShader,
        fragmentShader: TextureShader.fragmentShader,
      });

      var mesh = new THREE.Mesh(geometry, this.shaderMaterial);
      this.scene.add(mesh);
    },
    loadModel(modelName) {
      let that = this;
      const loader = new GLTFLoader();
      loader.setPath("/model/");
      loader.load(
        modelName,
        function (gltf) {
          that.gltfModel = gltf.scene;
          that.scene.add(gltf.scene);
        },
        function (xhr) {
          // 后台打印查看模型文件加载进度
          console.log(
            "加载完成的百分比" + (xhr.loaded / xhr.total) * 100 + "%"
          );
          var loadedData = Math.floor((xhr.loaded / xhr.total) * 100);
        }
      );
    },
    animate() {
      this.renderer.render(this.scene, this.camera);
      this.progress += 0.2;
      this.shaderMaterial.uniforms.time.value = this.progress;
      requestAnimationFrame(this.animate);
    },
    reset() {
      this.progress = 0.0;
    },
    addClass(index, event) {
      this.current = index;
      if (this.current == 0) {
        this.scene.remove(this.gltfModel);
        this.loadModel("a04.glb");
      }
      if (this.current == 1) {
        this.scene.remove(this.gltfModel);
        this.loadModel("a05.glb");
      }
      if (this.current == 2) {
        this.scene.remove(this.gltfModel);
        this.loadModel("a07.glb");
      }
      if (this.current == 3) {
        this.reset();
      }
    },
  },
};
</script>

<style scoped>
.dv-main {
  height: calc(100vh - 85px);
  width: 100%;
  display: block;
  box-sizing: border-box;
  background-color: rgb(82, 81, 81);
}
#menu {
  display: flex;
  cursor: pointer;
  transition: all 0.5s;
}
#menu li {
  font-size: 13px;
  width: 100px;
  height: 30px;
  line-height: 30px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  box-sizing: border-box;
  border-radius: 3px;
  text-align: center;
  justify-content: center;
  background-color: rgba(255, 255, 255, 0.3);
  margin-right: 2px;
}

#menu li:hover {
  background-color: rgba(255, 255, 255, 0.5);
}

#menu li:active {
  background-color: rgba(255, 177, 69, 1) !important;
  color: black;
  box-shadow: 0 0 5px yellow;
}

.blue {
  background-color: rgba(255, 177, 69, 1) !important;
  color: black;
}
</style>
